import { EnumChatMsgExecutedState, EnumChatMessageType, EnumMyChatEventType, EnumSender, EnumMyChatCardAction, EnumMyChatCardIcon, MyChatEventResult, MyChatMsgResult } from "@/apis/endpoint/model"
import { getMychatMsgdetailId, postMychatExecutecardactionId, postMychatMsgsId, postMychatSendmsgId } from "@/apis/endpoint/myChat"
import { useRef, useState } from "react"
import { useImmer } from "use-immer"
import Taro from "@tarojs/taro"
import { RouteParams } from "../types"
import { isSetValue } from "@/utils/helper"
import { dateFormat } from "@/utils/date"
import { handlePreview } from "@/utils/app"

export function useMessages(params: RouteParams) {
  const pageIndex = useRef(1)
  const [messages, setMessages] = useImmer<MyChatMsgResult[]>([])
  const [input, setInput] = useState("")
  const hasNext = useRef(true)
  const relativeMsgId = useRef(-1)
  const [scrollIntoView, setScrollIntoView] = useState<string>()
  const requestCardTypes = useRef([EnumChatMessageType.HR求简历, EnumChatMessageType.HR换微信, EnumChatMessageType.HR换手机])
  const specialMessageTypes = useRef([
    EnumChatMessageType.文本,
    EnumChatMessageType.图片,
    EnumChatMessageType.视频,
    EnumChatMessageType.语音,
    EnumChatMessageType.文件,
    EnumChatMessageType.位置,
    EnumChatMessageType.简历,
    EnumChatMessageType.手机,
    EnumChatMessageType.微信,
    EnumChatMessageType.系统,
  ])
  function isSpecialMessage(message: MyChatMsgResult) {
    return specialMessageTypes.current.includes(message.type)
  }
  function isRequestCardType(message: MyChatMsgResult) {
    return requestCardTypes.current.includes(message.type)
  }
  function fetchMessageList(refresh = false) {
    if (refresh) pageIndex.current = 1
    return postMychatMsgsId(Number(params.id), {
      page: {
        pageIndex: pageIndex.current,
        pageSize: 20
      },
      search: {},
      sort: {
        reverse: true
      }
    }).send()
    .then(({ items, count }) => {
      const nextMessages = pageIndex.current === 1 ? items.reverse() : items.reverse().concat(messages)
      setMessages(nextMessages)
      hasNext.current = count > nextMessages.length
      if (refresh) scrollToLast(nextMessages[nextMessages.length - 1]?.id)
    })
  }
  function getNextMessage(messageId: number) {
    return getMychatMsgdetailId(messageId).send()
    .then(message => {
      setMessages(draft => {
        const index = draft.findIndex(item => item.id === messageId)
        if (index === -1) {
          draft.push(message)
        } else {
          draft.splice(index, 1, message)
        }
      })
      scrollToLast(message.id)
    })
  }
  function scrollToLast(messageId: number) {
    if (isSetValue(messageId)) {
      setTimeout(() => {
        setScrollIntoView(`scroll_into_view_${messageId}`)
      }, 1500);
    }
  }

  function onScrollToUpper() {
    if (hasNext.current) {
      pageIndex.current++
      fetchMessageList()
    }
  }
  async function handleSend() {
    const content = input.trim()
    if (!content) return
    setInput("")
    await postMychatSendmsgId(Number(params.id), {
      type: EnumChatMessageType.文本,
      content
    }).send()
    const createTime = dateFormat(void 0, "long")
    const id = relativeMsgId.current--
    setMessages(draft => {
      draft.push({
        content,
        type: EnumChatMessageType.文本,
        createTime,
        readTime: createTime,
        id,
        isRead: true,
        sender: EnumSender.求职者,
        conversationId: Number(params.id)
      } as MyChatMsgResult)
    })
    scrollToLast(id)
  }
  function handleSocketMessage(data: string) {
    const incomingData: MyChatEventResult = JSON.parse(data)
    if (incomingData.type === EnumMyChatEventType.聊天消息) {
      getNextMessage(incomingData.id!)
    }
  }
  async function handleRequestCard(message: MyChatMsgResult, action: EnumMyChatCardAction, actionType: "reject" | "agreen") {
    if (actionType === "reject") {
      let content;
      if (message.cardContent.icon === EnumMyChatCardIcon.简历卡片) {
        content = "确定不向对方发送简历吗?"
      } else if (message.cardContent.icon === EnumMyChatCardIcon.微信卡片) {
        content = "确定不与对方交换微信吗?"
      } else if (message.cardContent.icon === EnumMyChatCardIcon.手机卡片) {
        content = "确定不与对方交换电话吗?"
      }
      const { confirm } = await Taro.showModal({
        content,
        cancelText: "关闭",
        confirmText: "确认",
        confirmColor: "#0768FA",
      })
      if (!confirm) return
    }
    const nextMessageId = await postMychatExecutecardactionId(Number(params.id), {
      action,
      chatMsgId: message.id
    }).send()
    nextMessageId && await getNextMessage(nextMessageId)
    setMessages(draft => {
      const currentMessage = draft.find(item => item.id === message.id)
      currentMessage!.executedState = actionType === "agreen" ? EnumChatMsgExecutedState.同意 : EnumChatMsgExecutedState.拒绝
    })
    Taro.showToast({
      title: "操作成功",
      icon: "success"
    })
  }
  function handleCopyText(text: string) {
    Taro.setClipboardData({
      data: text
    })
  }
  function handleCallphone(phoneNumber: string) {
    Taro.makePhoneCall({
      phoneNumber
    })
  }
  async function handleInterviewInvite(message: MyChatMsgResult, action: EnumMyChatCardAction) {
    const nextMessageId = await postMychatExecutecardactionId(message.conversationId, {
      action,
      chatMsgId: message.id
    }).send()
    const accepted = action === EnumMyChatCardAction.求职者同意面试邀请
    Taro.showToast({
      title: accepted ? '面试已接受' : '面试已拒绝',
      icon: 'none'
    })
    nextMessageId && await getNextMessage(nextMessageId)
    setMessages(draft => {
      const currentMessage = draft.find(item => item.id === message.id)
      currentMessage!.executedState = accepted ? EnumChatMsgExecutedState.同意 : EnumChatMsgExecutedState.拒绝
    })
  }
  return {
    isRequestCardType,
    isSpecialMessage,
    messages,
    input,
    setInput,
    scrollIntoView,
    fetchMessageList,
    onScrollToUpper,
    handleSend,
    handleSocketMessage,
    handleRequestCard,
    handleCopyText,
    handleCallphone,
    getNextMessage,
    previewResume: handlePreview,
    handleInterviewInvite
  }
}
